﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using HandyControl.Controls;
using BtLabelBLL;
using System.IO;
using System.Threading;
using BtLabelTool;

namespace 功能测试软件.View
{
    /// <summary>
    /// SingelTestView.xaml 的交互逻辑
    /// </summary>
    public partial class SingelTestView : UserControl
    {
        /// <summary>
        /// 数据库对象
        /// </summary>
        private BtLabelModel.TestDbModel.Test_Table resultDb = new BtLabelModel.TestDbModel.Test_Table();
        /// <summary>
        /// 测试配置
        /// </summary>
        public Model.TestModel _testModel = new Model.TestModel();
        public ViewModel.SingelTestViewModel viewModel = new ViewModel.SingelTestViewModel();
        /// <summary>
        /// 测试方法类
        /// </summary>
        private BLL.SingelTestViewBLL singelTestViewBLL = new BLL.SingelTestViewBLL();
        /// <summary>
        /// 继电器串口方法类
        /// </summary>
        private RelayUartBLL relayUartBLL = new RelayUartBLL();
        /// <summary>
        /// 通道串口方法类
        /// </summary>
        private ChannelUartBLL channelBLL = new ChannelUartBLL();
        /// <summary>
        /// 万用表方法类
        /// </summary>
        private MultimeterBLL multimeterBLL = new MultimeterBLL();
        /// <summary>
        /// 测试线程
        /// </summary>
        private Thread thread1 = null;
        /// <summary>
        /// 测试线程
        /// </summary>
        private Thread thread2 = null;
        private bool isTodayRetest = false;


        public SingelTestView()
        {
            HandyControl.Tools.ConfigHelper.Instance.SetLang("zh-cn");
            InitializeComponent();
            DataContext = viewModel;
        }
        /// <summary>
        /// 初始化通道测试
        /// </summary>
        /// <param name="testModel">通道测试配置</param>
        public void Init(Model.TestModel testModel)
        {
            try
            {
                //viewModel = new ViewModel.SingelTestViewModel();
                //传入参数
                singelTestViewBLL._singelTestView = this;
                singelTestViewBLL._testModel = testModel;
                //初始化界面
                singelTestViewBLL.ReadPic();
                singelTestViewBLL.InitView(viewModel);
                singelTestViewBLL.InitStep(viewModel);
                //初始化串口
                singelTestViewBLL.InitPort();

                //传入参数
                channelBLL._port = testModel.ChannelPort;
                channelBLL._RichTextBoxInfo = testModel.RichTextBoxLog;
                //传入参数
                relayUartBLL.port = testModel.RelayPort;
                relayUartBLL._RichTextBoxInfo = testModel.RichTextBoxLog;
                ////传入参数
                multimeterBLL._addr = TestView.config.MultimeterUsbAddr;
                multimeterBLL._richTextBoxInfo = testModel.RichTextBoxLog;

                _testModel = testModel;
            }
            catch (Exception ex)
            {
                Growl.Error(ex.Message);
                BtLabelTool.LogHelper.WriteLog(ex.ToString());
            }
        }

        private void Border_MouseMove(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Hand;
        }

        private void Border_MouseLeave(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Arrow;
        }

        public void BorderChannel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            try
            {
                //判断通道是否开启
                if (_testModel.ChannelEnable == false)
                {
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, _testModel.ChannelNo + "通道未开启！");
                    return;
                }
                //判断继电器串口
                if (_testModel.RelayPort.IsOpen == false)
                {
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, "继电器串口未打开！");
                    return;
                }
                //判断通道串口
                if (_testModel.ChannelPortname == "" || SerialPort.GetPortNames().Contains(_testModel.ChannelPortname) == false)
                {
                    Growl.Warning(_testModel.ChannelNo + "通道未配置串口！");
                    return;
                }
                //打开通道串口
                singelTestViewBLL.OpenPorts();
                if (_testModel.ChannelPort.IsOpen == false)
                {
                    Growl.Error(_testModel.ChannelNo + "通道串口打开失败！");
                    return;
                }
                //检查测试状态
                if (TestView.ChannelsStep[_testModel.ChannelNo - 1] != Model.StepModel.Step.Wait
                    && TestView.ChannelsStep[_testModel.ChannelNo - 1] != Model.StepModel.Step.isOk
                    && TestView.ChannelsStep[_testModel.ChannelNo - 1] != Model.StepModel.Step.GetMac)
                {
                    Growl.Error("通道" + _testModel.ChannelNo + "正在测试!");
                    return;
                }
                //判断测试线程
                if (thread1 != null)
                {
                    thread1.Abort();
                    BtLabelTool.CommonHelper.Delay(100);
                    thread1 = null;
                }
                //启动测试线程
                thread1 = new Thread(TestFlow);
                thread1.Start();
            }
            catch (Exception ex)
            {
                Growl.Error(ex.Message);
                BtLabelTool.LogHelper.WriteLog(ex.ToString());
            }
        }

        private void BorderRestart_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            try
            {
                //开始测试
                BorderChannel_MouseLeftButtonUp(null, null);
            }
            catch (Exception ex)
            {
                Growl.Error(ex.Message);
                BtLabelTool.LogHelper.WriteLog(ex.ToString());
            }
        }

        public void BorderCancel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            try
            {
                if (TestView.ChannelsStep[_testModel.ChannelNo - 1] != Model.StepModel.Step.Wait)
                {
                    //测试失败显示
                    FailResult();
                    //停止线程
                    if (thread1 != null)
                    {
                        thread1.Abort();
                        BtLabelTool.CommonHelper.Delay(1000);
                        thread1 = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Growl.Warning(ex.Message);
                BtLabelTool.LogHelper.WriteLog(ex.ToString());
            }

        }

        private void BorderPass_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            try
            {

                //确认
                if (viewModel.isokStepColor == Brushes.Orange)
                {
                    //蓝牙强度判断
                    if (viewModel.dBmStepColor!=Brushes.YellowGreen)
                    {
                        Growl.Warning(_testModel.ChannelNo+"通道信号强度检测未通过！");
                        return;
                    }
                    
                    if (TestView.ChannelsStep[_testModel.ChannelNo - 1] == Model.StepModel.Step.CurrentTest)
                    {
                        Growl.Warning("通道" + _testModel.ChannelNo + "正在电流测试!");
                        return;
                    }

                    thread2 = new Thread(() =>
                    {
                        try
                        {
                            //电流测试
                            TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.CurrentTest;
                            Dispatcher.Invoke(() => { viewModel.CurStepColor = Brushes.Orange; });
                            UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Orange, "----电流测试----");
                            //等待所有通道电流测试
                            UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Orange, "----等待所有通道开始电流测试----");
                            WaitCurrentTest();
                            UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----等待所有通道完成----");
                            for (int i = 0; i < TestView.ChannelsStep.Count; i++)
                            {
                                if (TestView.ChannelsStep[i] == Model.StepModel.Step.CurrentTest)
                                {
                                    if (i != _testModel.ChannelNo - 1)
                                    {
                                        i = -1;
                                        Thread.Sleep(200);
                                    }
                                    else
                                    {
                                        Thread.Sleep(200);
                                        break;
                                    }
                                }
                            }
                            if (CurrentTest() == false)
                            {
                                Dispatcher.Invoke(() => { viewModel.CurStepColor = Brushes.Tomato; });
                                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, "----电流测试失败----");
                                FailResult();
                                return;
                            }
                            Dispatcher.Invoke(() => { viewModel.CurStepColor = Brushes.YellowGreen; });
                            UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----电流测试成功----");
                            //测试结果保存
                            resultDb.time = DateTime.Now;
                            if (TestView.resultDAL.Update(resultDb) == false)
                            {
                                Growl.Error("本地数据库保存失败！");
                                return;
                            }
                            viewModel.isokStepColor = Brushes.YellowGreen;
                            //测试通过显示
                            PassResult();
                        }
                        catch (Exception ex)
                        {
                            Growl.Error(ex.Message);
                            BtLabelTool.LogHelper.WriteLog(ex.ToString());
                        }
                    });
                    thread2.Start();
                }
            }
            catch (Exception ex)
            {
                Growl.Error(ex.Message);
                BtLabelTool.LogHelper.WriteLog(ex.ToString());
            }
        }
        /// <summary>
        /// 测试主流程
        /// </summary>
        private void TestFlow()
        {
            try
            {
                //数据库对象
                resultDb = new BtLabelModel.TestDbModel.Test_Table();

                //通道界面初始化
                singelTestViewBLL.InitStep(viewModel);
                UiBLL.RichTextBoxClearText(_testModel.RichTextBoxLog);

                //获取产品mac
                TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.GetMac;
                Dispatcher.Invoke(() => { viewModel.MacStepColor = Brushes.Orange; });
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Orange, "----查询MAC地址----");
                if (GetMac() == false)
                {
                    Dispatcher.Invoke(() => { viewModel.MacStepColor = Brushes.Tomato; });
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, "----查询MAC地址失败----");
                    FailResult();
                    return;
                }
                Dispatcher.Invoke(() => { viewModel.MacStepColor = Brushes.YellowGreen; });
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----查询MAC地址成功----");
                //截取版本号 todo:

                //异步得到蓝牙强度
                WaitDbm();

                //注册后台 todo:

                //点灯测试
                if (_testModel.ChannelRgbEnable == true)
                {
                    TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.LightRgb;
                    Dispatcher.Invoke(() => { viewModel.RgbStepColor = Brushes.Orange; });
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Orange, "----点灯测试----");
                    if (LightRgb() == false)
                    {
                        Dispatcher.Invoke(() => { viewModel.RgbStepColor = Brushes.Tomato; });
                        UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, "----点灯测试失败----");
                        FailResult();
                        return;
                    }
                    Dispatcher.Invoke(() => { viewModel.RgbStepColor = Brushes.YellowGreen; });
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----点灯测试成功----");
                }

                //刷图测试
                if (_testModel.ChannelPicEnable == true)
                {
                    TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.WritePic;
                    Dispatcher.Invoke(() => { viewModel.PicStepColor = Brushes.Orange; });
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Orange, "----刷图----");
                    if (WritePic() == false)
                    {
                        Dispatcher.Invoke(() => { viewModel.PicStepColor = Brushes.Tomato; });
                        UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, "----刷图失败----");
                        FailResult();
                        return;
                    }
                    Dispatcher.Invoke(() => { viewModel.PicStepColor = Brushes.YellowGreen; });
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----刷图成功----");
                }
                //确认测试结果
                TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.isOk;
                Dispatcher.Invoke(() =>{viewModel.isokStepColor = Brushes.Orange;});
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----确认测试结果----");
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("中止线程"))
                {
                    return;
                }
                Growl.Error(ex.Message);
                BtLabelTool.LogHelper.WriteLog(ex.ToString());
            }
        }

        private bool CurrentTest()
        {
            try
            {
                lock (TestView.RelayPortLock)
                {
                    double current = 0;
                    //断开所有通道继电器
                    if (relayUartBLL.CloseAll() == false)
                    {
                        return false;
                    }
                    Thread.Sleep(1000);
                    //闭合当前通道继电器
                    if (relayUartBLL.OpenChannel(_testModel.ChannelNo) == false)
                    {
                        return false;
                    }
                    CommonHelper.Delay(2000);
                    //进入低功耗
                    if (channelBLL.InLowPower() == false)
                    {
                        return false;
                    }
                    //断开当前通道串口继电器
                    if (relayUartBLL.CloseChannelPort(_testModel.ChannelNo) == false)
                    {
                        return false;
                    }
                    //采集电流 
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "采集电流");
                    //采集等待
                    bool isOk = multimeterBLL.GetCurrent(ref current);
                    if (isOk == false)
                    {
                        UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "采集电流失败");
                        return false;
                    }
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, current + "uA");
                    if (current > _testModel.CurrentMax)
                    {
                        UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "电流过大");
                        return false;
                    }
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "采集电流完成");
                    //断开当前通道继电器
                    if (relayUartBLL.CloseChannel(_testModel.ChannelNo) == false)
                    {
                        return false;
                    }
                    resultDb.current = current.ToString();
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void WaitCurrentTest()
        {
            Task.Factory.StartNew(() =>
            {
            //todo 超时?
            label1:
                bool channel1 = TestView.ChannelsStep[0] == Model.StepModel.Step.CurrentTest || TestView.ChannelsStep[0] == Model.StepModel.Step.Wait;
                bool channel2 = TestView.ChannelsStep[1] == Model.StepModel.Step.CurrentTest || TestView.ChannelsStep[1] == Model.StepModel.Step.Wait;
                bool channel3 = TestView.ChannelsStep[2] == Model.StepModel.Step.CurrentTest || TestView.ChannelsStep[2] == Model.StepModel.Step.Wait;
                bool channel4 = TestView.ChannelsStep[3] == Model.StepModel.Step.CurrentTest || TestView.ChannelsStep[3] == Model.StepModel.Step.Wait;
                bool channel5 = TestView.ChannelsStep[4] == Model.StepModel.Step.CurrentTest || TestView.ChannelsStep[4] == Model.StepModel.Step.Wait;
                //所有通道不处于等待电流测试
                if ((channel1 && channel2 && channel3 && channel4 && channel5) == false)
                {
                    Thread.Sleep(1000);
                    goto label1;
                }
            }).Wait();
        }

        private bool GetMac()
        {
            try
            {
            label1:
                lock (TestView.RelayPortLock)
                {
                    //断开当前通道继电器
                    if (relayUartBLL.CloseChannel(_testModel.ChannelNo) == false)
                    {
                        return false;
                    }
                    Thread.Sleep(1000);
                    //闭合当前通道继电器
                    if (relayUartBLL.OpenChannel(_testModel.ChannelNo) == false)
                    {
                        return false;
                    }
                };
                //查询Mac
                string mac = "";
                string err = "";
                bool isOk = channelBLL.GetMac(ref mac,ref err);
                if (isOk == false)
                {
                    if (err=="null")
                    {
                        CommonHelper.Delay(100);
                        goto label1;
                    }
                    else
                    {
                        return false;
                    }
                }
                Dispatcher.Invoke(() => {viewModel.Mac = mac; });
                //查重
                isTodayRetest = false;
                var model = TestView.resultDAL.GetModel(mac);
                if (model != null)
                {
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "MAC重复");
                    MessageBoxResult result = HandyControl.Controls.MessageBox.Ask("通道" + _testModel.ChannelNo + "发现重复MAC,确定继续测试？", "警告");
                    if (result == MessageBoxResult.Cancel)
                    {
                        return false;
                    }
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "继续测试");
                    if (model.time > DateTime.Today)
                    {
                        isTodayRetest = true;
                    }
                }
                resultDb.mac = mac;
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void WaitDbm()
        {
            Task.Factory.StartNew(() =>
            {
                Dispatcher.Invoke(() => { viewModel.dBmStepColor = Brushes.Orange; });
                while (viewModel.dBmStepColor == Brushes.Orange)
                {
                    //蓝牙搜索未开启
                    if (TestView.isScan == false)
                    {
                        Dispatcher.Invoke(() => { viewModel.dBmStepColor = Brushes.Tomato; });
                        BorderCancel_MouseLeftButtonUp(null, null);
                        break;
                    }
                    //从当前搜索到的蓝牙中查找
                    BtLabelModel.DeviceModel device = null;
                    lock (TestView.MacsLock)
                    {
                        device = TestView.Macs.Where(it => it.Address == viewModel.Mac).FirstOrDefault();
                    }
                    if (device == null)
                    {
                        continue;
                    }
                    //判断蓝牙强度
                    if (device.DBm < _testModel.dBmMin)
                    {
                        Dispatcher.Invoke(() => { viewModel.dBm = device.DBm.ToString(); viewModel.dBmStepColor = Brushes.Tomato; });
                        BorderCancel_MouseLeftButtonUp(null, null);
                        break;
                    }
                    resultDb.dbm = device.DBm.ToString();
                    Dispatcher.Invoke(() => { viewModel.dBm = device.DBm.ToString(); viewModel.dBmStepColor = Brushes.YellowGreen; });
                    Thread.Sleep(500);
                }
            });
        }

        private bool LightRgb()
        {
            try
            {
                //点灯测试
                Dispatcher.Invoke(() => { viewModel.RgbColor = Brushes.Orange; });
                bool isOk = channelBLL.LightRgb();
                if (isOk == false)
                {
                    Dispatcher.Invoke(() => { viewModel.RgbColor = Brushes.Tomato; });
                    return false;
                }
                Dispatcher.Invoke(() => { viewModel.RgbColor = Brushes.ForestGreen; });
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private bool WritePic()
        {
            try
            {
                //生成图片
                //viewModel.Mac = "CB 26 FF 01 00 1A";
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "生成图片");
                string path = channelBLL.CreatePic(_testModel.ChannelPicTemp, viewModel.Mac);
                Dispatcher.Invoke(() =>
                {
                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.CacheOption = BitmapCacheOption.OnLoad;
                    bi.UriSource = new Uri(path, UriKind.RelativeOrAbsolute);
                    bi.EndInit(); 
                    viewModel.Pic = bi.Clone();
                });
                //读取图片
                string bitmapstr = "";
                System.Drawing.Bitmap bitmap = channelBLL.GetBitMap(path, ref bitmapstr);
                //UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.SteelBlue, bitmapstr);
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.SteelBlue, "......");
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "生成图片完成");
                //刷图
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "刷入图片");
                bool isOk = channelBLL.WritePic(bitmap, _testModel.BarDelay);
                if (isOk == false)
                {
                    UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "刷入图片失败");
                    return false;
                }
                bitmap.Dispose();
                UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Blue, "刷入图片完成");
                if (_testModel.ChannelPicTemp == "QR")
                {
                    //异步删除图片
                    singelTestViewBLL.DeletePic(path);
                }
                resultDb.image = bitmapstr;
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        public void PassResult()
        {
            if (isTodayRetest == false)
            {
                lock (TestView.textBlockCount)
                {
                    TestView.textBlockCount.Dispatcher.Invoke(() =>
                    {
                        int count = int.Parse(TestView.textBlockCount.Text) + 1;
                        TestView.textBlockCount.Text = count.ToString();
                    });
                }
            }
            Dispatcher.Invoke(() =>
            {
                viewModel.ResultStepColor = Brushes.YellowGreen;
                viewModel.ResultColor = Brushes.ForestGreen;
                viewModel.Result = "Pass";
                viewModel.Count++;
            });
            relayUartBLL.CloseChannel(_testModel.ChannelNo);
            TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.Wait;
            UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.ForestGreen, "----测试成功----");
        }
        public void FailResult()
        {
            Dispatcher.Invoke(() =>
            {
                viewModel.ResultStepColor = Brushes.Tomato;
                viewModel.ResultColor = Brushes.Tomato;
                viewModel.Result = "Fail";
            });
            relayUartBLL.CloseChannel(_testModel.ChannelNo);
            TestView.ChannelsStep[_testModel.ChannelNo - 1] = Model.StepModel.Step.Wait;
            UiBLL.RichTextBoxAppendText(_testModel.RichTextBoxLog, Brushes.Tomato, "----测试失败----");
        }
    }
}
